package com.sun.umbrella.service.shiro.filter.resources.impl;

import com.alibaba.fastjson.JSON;
import com.sun.core.enums.BaseBizEnum;
import com.sun.core.enums.BaseErrorEnum;
import com.sun.core.enums.EnableEnum;
import com.sun.core.enums.YnEnum;
import com.sun.core.ex.BusinessCheckFailException;
import com.sun.core.ex.BusinessProcessFailException;
import com.sun.core.web.page.PageUtil;
import com.sun.star.base.util.BeanUtil;
import com.sun.umbrella.domain.query.FilterChainsQuery;
import com.sun.umbrella.domain.vo.FilterChainsSaveVO;
import com.sun.umbrella.domain.vo.FilterChainsUpdateVO;
import com.sun.umbrella.domain.vo.FilterChainsVO;
import com.sun.umbrella.service.shiro.filter.resources.FilterChainService;
import com.sun.umbrella.dao.FilterChainsMapper;
import com.sun.umbrella.domain.entity.FilterChainsDO;
import com.sun.umbrella.session.ContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

/**
 * @author Jay
 * @version v1.0
 * @description 过滤器资源
 * @date 2017-12-08 15:34
 */
@Service
@Slf4j
public class FilterChainServiceImpl implements FilterChainService {


    @Autowired
    private FilterChainsMapper filterChainsMapper;


    @Autowired
    private ContextHolder contextHolder;


    /**
     * 根据sysId查询到对应的过滤器资源
     *
     * @param sysId
     * @return
     */
    @Override
    public List<FilterChainsDO> getFilterChainsBySysId(Integer sysId) {
        if (sysId == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "系统id不能为空");
        }
        return filterChainsMapper.selectBySysId(sysId);
    }


    /**
     * 分页查询过滤器配置列表
     *
     * @param filterChainsQuery
     * @param pageable
     * @return
     */
    @Override
    public Page<FilterChainsVO> queryFilterChainsList(FilterChainsQuery filterChainsQuery, Pageable pageable) {
        // 查询总量
        int count = filterChainsMapper.countFilterChainsList(filterChainsQuery);
        if (count == BaseBizEnum.ZERO.getKey()) {
            return PageUtil.newEmptyPage(pageable);
        }
        // 填充分页参数
        PageUtil.fillParam(filterChainsQuery, pageable);
        List<FilterChainsDO> filterChainsDOList = filterChainsMapper.selectFilterChainsList(filterChainsQuery);
        log.info("分页查询过滤器配置列表返回值为:{}", JSON.toJSONString(filterChainsDOList));
        // 转换
        List<FilterChainsVO> filterChainsVOList = BeanUtil.copyList(filterChainsDOList, FilterChainsVO.class);
        if (CollectionUtils.isEmpty(filterChainsVOList)) {
            return PageUtil.newEmptyPage(pageable);
        }
        return PageUtil.newPage(filterChainsVOList, pageable, count);
    }


    /**
     * 删除过滤器配置记录
     *
     * @param id
     * @param sysId
     * @return
     */
    @Transactional(rollbackFor = BusinessProcessFailException.class)
    @Override
    public Boolean deleteFilterChain(Integer id, Integer sysId) {
        if (id == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "id 不能为空");
        }
        if (sysId == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "sysId 不能为空");
        }
        // 查询记录是否存在
        FilterChainsDO filterChainsDO = filterChainsMapper.selectBySysIdAndId(sysId, id);
        if (filterChainsDO == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "要删除的记录不存在");
        }
        Integer modifier = contextHolder.getSessionContext().getUserId();
        // 删除记录
        if (filterChainsMapper.deletedFilterChains(sysId, id, modifier) != BaseBizEnum.FIRST.getKey()) {
            throw new BusinessProcessFailException("删除资源配置记录失败", BaseErrorEnum.UPDATE_ERROR.getCode());
        }
        return Boolean.TRUE;
    }


    /**
     * 保存过滤器配置记录
     *
     * @param filterChainsSaveVO
     * @return
     */
    @Transactional(rollbackFor = BusinessProcessFailException.class)
    @Override
    public Boolean saveFilterChain(FilterChainsSaveVO filterChainsSaveVO) {
        // 校验参数
        this.checkParams(filterChainsSaveVO);
        // 保存记录
        FilterChainsDO filterChainsDO = this.fillFilterChainsDO(filterChainsSaveVO);
        if (filterChainsMapper.insertFilterChains(filterChainsDO) != BaseBizEnum.FIRST.getKey()) {
            throw new BusinessProcessFailException("保存过滤器配置失败", BaseErrorEnum.SAVE_ERROR.getCode());
        }
        return Boolean.TRUE;
    }

    /**
     * 修改启用 禁用 状态
     *
     * @param id
     * @param enabledState
     * @return
     */
    @Transactional(rollbackFor = BusinessProcessFailException.class)
    @Override
    public Boolean updateFilterEnable(Integer id, Integer enabledState) {
        if (id == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "id不能为空");
        }
        if (enabledState == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "enabledState不能为空");
        }
        if (!enabledState.equals(EnableEnum.YES.getKey()) && !enabledState.equals(EnableEnum.NO.getKey())) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "enabledState传入值不合法");
        }
        Integer modifier = contextHolder.getSessionContext().getUserId();
        if (filterChainsMapper.updateFilterChainsEnable(id, modifier, enabledState) != BaseBizEnum.FIRST.getKey()) {
            throw new BusinessProcessFailException(" 修改启用禁用状态失败", BaseErrorEnum.SAVE_ERROR.getCode());
        }
        return Boolean.TRUE;
    }

    /**
     * 修改过滤器配置资源
     *
     * @param filterChainsUpdateVO
     * @return
     */
    @Override
    public Boolean updateFilterChain(FilterChainsUpdateVO filterChainsUpdateVO) {
        // 参数校验
        this.checkUpdateParams(filterChainsUpdateVO);
        FilterChainsDO filterChainsDO = new FilterChainsDO();
        BeanUtil.copyProperties(filterChainsUpdateVO, filterChainsDO);
        filterChainsDO.setModifier(contextHolder.getSessionContext().getUserId());
        if (filterChainsMapper.updateFilterChains(filterChainsDO) != BaseBizEnum.FIRST.getKey()) {
            throw new BusinessProcessFailException(" 修改过滤器配置资源失败", BaseErrorEnum.SAVE_ERROR.getCode());
        }
        return Boolean.TRUE;
    }


    /*================================================private method================================================*/


    /**
     * 参数转换
     *
     * @param filterChainsSaveVO
     * @return
     */
    private FilterChainsDO fillFilterChainsDO(FilterChainsSaveVO filterChainsSaveVO) {
        if (filterChainsSaveVO == null) {
            return null;
        }
        FilterChainsDO filterChainsDO = new FilterChainsDO();
        BeanUtil.copyProperties(filterChainsSaveVO, filterChainsDO);
        filterChainsDO.setIsDeleted(YnEnum.N.getKey());
        filterChainsDO.setCreator(contextHolder.getSessionContext().getUserId());
        filterChainsDO.setModifier(contextHolder.getSessionContext().getUserId());
        filterChainsDO.setGmtModified(new Date());
        filterChainsDO.setGmtCreate(new Date());
        filterChainsDO.setEnabledState(EnableEnum.YES.getKey());
        return filterChainsDO;
    }


    /**
     * 校验参数
     *
     * @param filterChainsSaveVO
     */
    private void checkParams(FilterChainsSaveVO filterChainsSaveVO) {
        if (filterChainsSaveVO == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "入参不能为空");
        }
        if (StringUtils.isEmpty(filterChainsSaveVO.getFilterRes())) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "过滤器符号不能为空");
        }
        if (StringUtils.isEmpty(filterChainsSaveVO.getMatchSign())) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "匹配符号不能为空");
        }
        if (filterChainsSaveVO.getIdxShow() == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "资源加载顺序不能为空");
        }
        if (filterChainsSaveVO.getSysId() == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "sysId不能为空");
        }
    }


    /**
     * 校验参数
     *
     * @param filterChainsUpdateVO
     */
    private void checkUpdateParams(FilterChainsUpdateVO filterChainsUpdateVO) {
        if (filterChainsUpdateVO == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "入参不能为空");
        }
        if (filterChainsUpdateVO.getId() == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "id不能为空");
        }
        if (StringUtils.isEmpty(filterChainsUpdateVO.getFilterRes())) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "过滤器符号不能为空");
        }
        if (StringUtils.isEmpty(filterChainsUpdateVO.getMatchSign())) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "匹配符号不能为空");
        }
        if (filterChainsUpdateVO.getIdxShow() == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "资源加载顺序不能为空");
        }
        if (filterChainsUpdateVO.getSysId() == null) {
            throw new BusinessCheckFailException(BaseErrorEnum.BNS_CHK_ERROR.getCode(), "sysId不能为空");
        }
    }


}
